<template>
  <div
    :class="{
      'click-score-mode': isClickMode && clickScore > -1
    }"
    style="position: relative; width: 100%"
    @click="onClickResult"
  >
    <slot></slot>
    <ScoreMark
      v-for="(mark, markIndex) in scoreMarks[props.currentIndex]"
      :key="markIndex"
      :mark="mark"
      @remove="removeMark(markIndex)"
      @add="modifyScore(markIndex, true)"
      @minus="modifyScore(markIndex, false)"
    ></ScoreMark>
  </div>
</template>

<script setup>
import { ref, watch, onBeforeUnmount } from 'vue'
import ScoreMark from './ScoreMark.vue'
import { scoreClickMitt } from '@/utils/tools/bus'
import { ElMessage } from 'element-plus'

const isClickMode = ref(false)
const scoreMarks = ref([])
const clickScore = ref(-1) //当前点击选中的分数
const scorePrefix = ref('')
const props = defineProps({
  totalScore: {
    type: Number,
    required: false,
    default: 0
  },
  locationList: {
    type: Array,
    required: false,
    default: () => []
  },
  currentIndex: {
    type: Number,
    required: false,
    default: 0
  },
  totalNum: {
    type: Number,
    required: false,
    default: 1
  }
})
const removeMark = index => {
  scoreMarks.value[props.currentIndex].splice(index, 1)
  scoreClickMitt.emit('change-score-marks', {
    marks: scoreMarks.value,
    updateScore: true,
    isClick: isClickMode.value
  })
}

const modifyScore = (index, isAdd) => {
  const { totalScore, currentIndex } = props
  const fullScore = totalScore

  // 计算当前总分
  const sumOfScores = scoreMarks.value.reduce(
    (total, group) =>
      total + group.reduce((acc, { score }) => acc + Number(score), 0),
    0
  )

  // 当前分数
  const scoreObj = scoreMarks.value[currentIndex][index]
  const { score } = scoreObj
  const prefix = score[0]
  const scoreNum = Number(score.substring(1))

  // 满分校验
  if (sumOfScores === fullScore && isAdd) {
    return ElMessage.warning('已加到满分，不可继续加分')
  }

  // 最低分校验
  if (
    sumOfScores + fullScore === 0 &&
    ((isAdd && prefix === '-') || (!isAdd && prefix === '+'))
  ) {
    return ElMessage.warning('已减到0分，不可继续减分')
  }

  // 更新分数
  scoreObj.score = `${prefix}${isAdd ? scoreNum + 1 : scoreNum - 1}`

  // 触发事件
  scoreClickMitt.emit('change-score-marks', {
    marks: scoreMarks.value,
    updateScore: true,
    isClick: isClickMode.value
  })
}

// 点击内容进行打分
const onClickResult = e => {
  if (!isClickMode.value || clickScore.value < 0) return

  const { totalScore, currentIndex } = props
  const fullScore = totalScore

  // 计算当前总分
  const sumOfScores = scoreMarks.value.reduce(
    (total, group) =>
      total + group.reduce((acc, { score }) => acc + Number(score), 0),
    0
  )

  const isAdding = scorePrefix.value === '+'
  const isSubtracting = scorePrefix.value === '-'

  // 检查是否超出范围
  if (isAdding) {
    if (sumOfScores === fullScore) {
      return ElMessage.warning('已加到满分，不可继续加分')
    }
    if (sumOfScores + clickScore.value > fullScore) {
      return ElMessage.warning('再加将大于满分，请选用其他分数')
    }
  }

  if (isSubtracting) {
    if (
      Math.abs(sumOfScores) === fullScore &&
      scoreMarks.value[currentIndex].length !== 0
    ) {
      return ElMessage.warning('已减到0分，不可继续减分')
    }
    if (Math.abs(sumOfScores) + clickScore.value > fullScore) {
      return ElMessage.warning('再减将小于0分，请选用其他分数')
    }
  }

  // 计算点击位置
  const { clientX, clientY, target } = e
  const { left, top, width, height } = target.getBoundingClientRect()
  scoreMarks.value[currentIndex].push({
    score: `${scorePrefix.value}${clickScore.value}`,
    x: pxToVw(clientX - left, width),
    y: pxToVw(clientY - top, height)
  })

  // 触发事件更新分数
  scoreClickMitt.emit('change-score-marks', {
    marks: scoreMarks.value,
    updateScore: true,
    isClick: isClickMode.value
  })
}

function pxToVw(pxValue, viewportWidth) {
  return (pxValue / viewportWidth) * 100
}
const initOnMitt = () => {
  // 获取是否为点击打分
  scoreClickMitt.on('is-click-score-mode', value => {
    isClickMode.value = value
  })
  // 获取选中的 点击的分数
  scoreClickMitt.on('change-click-value', ({ score, prefix }) => {
    if (!isClickMode.value) isClickMode.value = true
    ;(clickScore.value = score), (scorePrefix.value = prefix)
  })
  // 撤销操作
  scoreClickMitt.on('undo', () => {
    if (scoreMarks.value.length == 0) {
      return
    }
    scoreMarks.value[props.currentIndex].pop()
    scoreClickMitt.emit('change-score-marks', {
      marks: scoreMarks.value,
      updateScore: true,
      isClick: isClickMode.value
    })
  })
  // 清空打分点
  scoreClickMitt.on('clear-marks', () => {
    scoreMarks.value = Array.from({ length: props.totalNum }, () => [])
    scoreClickMitt.emit('change-score-marks', {
      marks: scoreMarks.value,
      updateScore: false,
      isClick: isClickMode.value
    })
  })
}

initOnMitt()

onBeforeUnmount(() => {
  scoreClickMitt.off('is-click-score-mode')
  scoreClickMitt.off('change-click-value')
  scoreClickMitt.off('undo')
  scoreClickMitt.off('clear-marks')
})
// 如果回评，之前有坐标
watch(
  () => props.locationList,
  val => {
    if (val.length) {
      isClickMode.value = true
      scoreMarks.value = props.locationList
    } else {
      isClickMode.value = false
      scoreMarks.value = Array.from({ length: props.totalNum }, () => [])
    }
    scoreClickMitt.emit('change-score-marks', {
      marks: scoreMarks.value,
      updateScore: true,
      isClick: isClickMode.value
    })
  },
  {
    immediate: true
  }
)
</script>

<style lang="less" scoped>
@baseURL: '@/assets/images/score-mark';
.click-score-mode {
  cursor:
    url('@{baseURL}/cursor-mark.png') 28 5,
    pointer;
}
</style>
